# ~*~ coding: utf-8 ~*~
from flask_login import current_user
from apps.extensions import db
from apps.codes.models import Project, Task, Filter, Permission
from apps.perms.mixin import PermissionRequiredMixin


class BasePermissionMixin(object):

    @staticmethod
    def get_filter():
        if current_user.is_admin:
            project_ids = db.session.query(Project.id).all()
        else:
            project_ids = db.session.query(Permission.project_id).\
                filter(Permission.user_id == current_user.id).\
                all()
        try:
            return list(zip(*project_ids))[0]
        except IndexError:
            return list()


class ProjectPermissionMixin(BasePermissionMixin, PermissionRequiredMixin):

    def get_queryset(self):
        project_ids = self.get_filter()
        return db.session.query(Project).filter(Project.id.in_(project_ids))

    def has_object_perm(self, *args, **kwargs):
        project_ids = self.get_filter()
        pk = kwargs.get('pk')

        if not pk:
            return super().has_object_perm(*args, **kwargs)

        if pk in project_ids:
            return True
        else:
            return False


class TaskPermissionMixin(BasePermissionMixin, PermissionRequiredMixin):

    def get_queryset(self):
        project_ids = self.get_filter()
        return db.session.query(Task).filter(Task.project_id.in_(project_ids))

    def has_object_perm(self, *args, **kwargs):
        project_ids = self.get_filter()
        pk = kwargs.get('pk')

        if not pk:
            return super().has_object_perm(*args, **kwargs)

        task = db.session.query(Task.project_id).filter(Task.id == pk).first()
        if task.project_id in project_ids:
            return True
        else:
            return False


class FilterPermissionMixin(BasePermissionMixin, PermissionRequiredMixin):

    def get_queryset(self):
        project_ids = self.get_filter()
        return db.session.query(Filter).filter(Filter.project_id.in_(project_ids))

    def has_object_perm(self, *args, **kwargs):
        project_ids = self.get_filter()
        pk = kwargs.get('pk')
        if not pk:
            return super().has_object_perm(*args, **kwargs)

        ft = db.session.query(Filter.project_id).filter(Filter.id == pk).first()
        if ft.project_id in project_ids:
            return True
        else:
            return False
